วันศุกร์ที่ 11 มกราคม พ.ศ. 2556

โปรแกรมสวิตซ์กดติด-กดดับ

    

โปรแกรมสวิตซ์กดติด-กดดับ เป็นอีกหนึ่งทักษะพื้นฐานในการเขียนโปรแกรมไมโครคอนโทรลเลอร์ PIC เพราะในการใช้งานจริงบางครั้งต้องใช้สวิตซ์ตัวเดียวในการควบคุมการทำงานของโปรแกรม เพื่อความสะดวกในการใช้งาน ซึ่งเราจะพาท่านมาศึกษาการเขียนโปรแกรมสวิตซ์กดติด-กดดับ กันครับ


ขั้นตอนที่ 1

 ประกอบวงจรตามรูปด้านล่าง ลงในโปรแกรม Proteus ครับ




คำสั่งที่ใช้ในการโปรแกรม

while()  เป็นคำสั่งทำงานซ้ำแบบมีเงื่อนไขครับ ซึ่งจะทำงานวนซ้ำไปเรื่อยๆจนกว่าเงื่อนไขจะเป็นเท็จ


output_x(...)   เป็นคำสั่งส่งข้อมูลออกทางเอาต์พุตในพอร์อตที่ต้องการตามค่าที่กำหนด เช่น output_b(0x01);

delay_ms(...)  เป็นคำสั่งหน่วงเวลา เช่น delay_ms(500); โปรแกรมจะหน่วงเวลา 500ms ซึ่งค่านี้เราสามารถเปลี่ยนแปลงได้ตามความต้องการครับ


set_tris_x()  เป็นคำสั่งกำหนดพอร์ตใช้งานให้พอร์ตอินพุต หรือเอาต์พุต โดยการกำหนดค่าให้กับฟังก์ชัน set_tris_x() เช่น set_tris_b(0x00); , set_tris_a(0xff);


value = input() เป็นคำสั่งอ่านข้อมูลจากพอร์ตอินพุตที่ต้องการ เช่น a=!input(pin_a0);

output_bit()  เป็นคำสั่งส่งข้อมูลออกทางเอาต์พุตในระดับบิต เช่น output_bit(pin_b0,a); 


ขั้นตอนที่ 2

เริ่มเขียนโปรแกรมกันเลยครับ



#include <16F84A.h>
#use delay(clock=4000000)
#fuses XT,NOWDT,NOPROTECT
#use fast_io(A)
#use fast_io(B)


int1 a;                                      //  คำสั่งประกาศตัวแปร a เป็นเลขจำนวนเต็มขนาน 1 บิต

void main()

{
  set_tris_a(0xff);                        //  คำสั่งกำหนดพอร์ต A เป็นพอร์ตอินพุตทั้งหมด
  set_tris_b(0x00);                      //  คำสั่งกำหนดพอร์ต B ให้เป็นพอร์ตเอาต์พุตทั้งหมด

  output_b(0b00000000);            //  คำสั่งเคลียร์พอร์ต B ให้เป็น 0 ทุกบิต

  a=0;                                       //  คำสั่งกำหนดค่า a=0
  
  while(true)                              //  คำสั่งวนซ้ำแบบมีเงื่อนไข
     {
        while(!input(pin_a0))         //  คำสั่งทำซ้ำ โดยรับค่าอินพุตจากพอร์ต a0
           { 
              a=~a;                        //  คำสั่งเปลี่ยนข้อมูล a เป็นตรงกันข้าม
              output_bit(pin_b0,a);   //  คำสั่งส่งข้อมูลออกทางเอาต์พุตขนาด 1 บิต

              while(!input(pin_a0))   //  คำสั่งทำซ้ำ โดยรับค่าอินพุตจากพอร์ต a0
                 {
                   delay_ms(100);     //  คำสั่งหน่วงเวลา 100 ms
                     
            }  

      }                                   
}






การทำงานของโปรแกรม


  •    เมื่อยังไม่มีการกดสวิตซ์
           คำสั่ง while(!input(pin_a0)) จะวนซ้ำการตรวจสอบว่ามีการกดสวิตซ์หรือไม่ หากไม่มีการกดสวิตซ์ก็จะวนซ้ำไปเรื่อยๆ โดยจะข้ามคำสั่งในวงเล็บปีกกาไป LED1 จึงไม่ติด
  •   เมื่อมีการกดสวิตซ์ 
          a=0 มีค่าเป็นลอจิก 0 เมื่อใส่เครื่องหมาย "~" เข้าไป (a=~a) จะมีการกลับสถานะข้อมูลจาก ลอจิก 0 เป็นลอจิก 1 (a=~a มีค่าเป็นลอจิก 1) ดังนั้น ค่า a = 1 เมื่อนำค่า a ส่งออกไปยังพอร์ตเอาต์พุตขา b0 LED1 จึงติด และเมื่อมีการกดสวิตซ์อีกครั้งก็ก็จะมีการกลับสถานะข้อมูลจากลอจิก 1 เป็นลอจิก 0 (a=~a มีค่าเป็นลอจิก 0) ดังนั้น ค่า a = 0 เมื่อนำค่า a ส่งออกไปยังพอร์ตเอาต์พุตขา b0 LED1 จึงดับ